#!/usr/bin/env coffee

import walk from '@rmw/walk'
import blake3_file from './lib/blake3.file'
import $,{Meta,Hash} from './db/mdbx'
import {existsSync} from 'fs'
import {stat} from 'fs/promises'
import chokidar from 'chokidar'
import {ROOT, relpath, normalize} from './misc/root'


_meta = ({mtimeMs,size}, {buffer})=>
  view = new DataView(buffer)
  view.setBigUint64 0, BigInt(parseInt mtimeMs), true
  view.setBigUint64 8, BigInt(size), true
  return

_update = ({size}, key, path, buf)=>
  blake = await blake3_file(path,size)
  buf.set(blake, 16)
  $ =>
    await Hash.put blake, key
    await Meta.put key, buf
    return

_rm = (key)=>
  bin = await Meta.get(key)
  if undefined == bin
    return
  $ =>
    await Meta.remove key
    await Hash.remove bin[16...48], key
    return
  return

do =>
  for i from Meta.getKeys(
    snapshot:false
  )
    if not existsSync normalize i
      _rm i

  chokidar.watch(
    ROOT
    awaitWriteFinish: true
  ).on(
    'add'
    (path, stat)=>
      key = relpath(path)
      meta = new Uint8Array 16
      _meta(stat,meta)

      buf = await Meta.get(key)
      if buf == undefined
        update = true
        buf = new Uint8Array 48
      else
        update = Buffer.compare(meta, buf[...16])

      if update
        buf.set(meta, 0)
        await _update stat, key, path, buf
      return
  ).on(
    'change'
    (path, stat)=>
      buf = new Uint8Array 48
      _meta(stat,buf)
      key = relpath path
      _update stat, key, path, buf
      return
  ).on(
    'unlink'
    (path)=>
      _rm relpath path
      return
  )
  return



